#include <renderdata.h>

void render_data_free(RenderData *data)
{
	int i = 0;
	IndexData *iData = &data->iData;
	VertexData *vData = &data->vData;

	if(NULL != iData->data && iData->isIndexCopy)
		pi_free(iData->data);
	if(NULL != vData->position && vData->isPosCopy)
		pi_free(vData->position);
	if(NULL != vData->normal && vData->isNormCopy)
		pi_free(vData->normal);
	if(NULL != vData->diffuse && vData->isDiffCopy)
		pi_free(vData->diffuse);
	for(i = 0; i < MAX_TEXSTAGE_NUM; ++i)
		if(NULL != vData->texCoord[i].coord &&  vData->isTexCoordCopy[i])
			pi_free(vData->texCoord[i].coord);
	pi_memset(data, 0, sizeof(RenderData));
}

int render_data_copy_index(RenderData *data, int idSize, int idNum, void *index)
{
	int size = 0;
	void *temp = NULL;
	if(0 < idNum && 0 < idSize)
	{
		size = idSize * idNum;
		data->iData.isIndexCopy = TRUE;
		temp = pi_malloc(size);
		if(NULL != index)
			pi_memcpy(temp, index, size);
	}
	render_data_set_index(data, idSize, idNum, temp);
	return size;
}

int render_data_copy_position(RenderData *data, PiVector3 *pos)
{
	int size = 0;
	void *temp = NULL;

	if(NULL != pos)
	{
		data->vData.isPosCopy = TRUE;
		size = sizeof(PiVector3) * data->vData.vertexCount;
		temp = pi_malloc(size);
		pi_memcpy(temp, pos, size);
	}
	render_data_set_position(data, temp);
	return size;
}

int render_data_copy_normal(RenderData *data, PiVector3 *normal)
{
	int size = 0;
	void *temp = NULL;

	if(NULL != normal)
	{
		data->vData.isNormCopy = TRUE;
		size = sizeof(PiVector3) * data->vData.vertexCount;
		temp = pi_malloc(size);
		pi_memcpy(temp, normal, size);
	}
	render_data_set_normal(data, temp);
	return size;
}

int render_data_copy_diffuse(RenderData *data, T3dColor *diffuse)
{
	int size = 0;
	void *temp = NULL;

	if(NULL != diffuse)
	{
		data->vData.isDiffCopy = TRUE;
		size = sizeof(T3dColor) * data->vData.vertexCount;
		temp = pi_malloc(size);
		pi_memcpy(temp, diffuse, size);
	}
	render_data_set_diffuse(data, temp);
	return size;
}

int render_data_tex_coord(RenderData *data, int stage, ETexCoordType type, float *coord)
{
	int size = 0;
	void *temp = NULL;

	if(NULL != coord)
	{
		switch(type)
		{
		case ETCT_ONE:
			size = 1 * sizeof(float);
			break;
		case ETCT_TWO:
			size = 2 * sizeof(float);
			break;
		case ETCT_THREE:
			size = 3 * sizeof(float);
			break;
		default:
			break;
		}
		if(0 < size)
		{
			size *= data->vData.vertexCount;
			temp = pi_malloc(size);
			pi_memcpy(temp, coord, size);
			data->vData.isTexCoordCopy[stage] = TRUE;
		}
	}
	render_data_set_tex_coord(data, stage, type, temp);
	return size;
}

void render_data_copy(RenderData *dst, RenderData *src)
{
	int i = 0, idSize = 0;
	
	if(NULL == src)
		return;

	render_data_set_geo_type(dst, src->type);
	render_data_set_cullmode(dst, src->cullMode);

	render_data_set_vertex_count(dst, src->vData.vertexCount);
	
	idSize = (EINDEX_16BIT == src->iData.type) ? sizeof(short) : sizeof(int);
	render_data_copy_index(dst, idSize,  src->iData.num, src->iData.data);
	render_data_copy_position(dst, src->vData.position);
	render_data_copy_normal(dst, src->vData.normal);
	render_data_copy_diffuse(dst, src->vData.diffuse);
	for(i = 0; i < MAX_TEXSTAGE_NUM; ++i)
		render_data_tex_coord(dst, i, src->vData.texCoord[i].type, src->vData.texCoord[i].coord);
}

void render_data_compute_aabb(RenderData *data)
{
	int i;
	PiVector3 *pos = data->vData.position;
	int numVertex = data->vData.vertexCount;
	pi_aabb_init(&data->box);
	for(i = 0; i < numVertex; ++i)
		pi_aabb_add_point(&data->box, &pos[i]);
}